Pythonによるデータ分析 | Rによる準周期データの分析

Pythonによる準周期データの分析

準周期タイプ のデータをPythonで分析する時の一連の手順になります。

元データ

データは、時刻付きのデータです。 センサーのデータには、0と1を使ってデータの変わり目を示す変数が入っていることがありますが、これにはありません。 下記のサンプルコードは、変わり目の変数を作るところからなので、このデータの扱いができれば、他の場合にも応用できます。
2次データの作成

1次データの分析

Pythonによるデータ全体の可視化 にあるPlotlyを使った方法で、データを見ます。 1次データ の分析になります。

import os #パッケージの読み込み
import pandas as pd
# パッケージの読み込み
import matplotlib.pyplot as plt
# パッケージの読み込み
import seaborn as sns
# パッケージの読み込み
%matplotlib inline
sns.set(font='HGMaruGothicMPRO')
# PandasのPlotのグラフの見た目をseaborn風にする。グラフのフォントを設定する
import plotly.express as px
#パッケージの読み込み
import plotly.io as pio
#パッケージの読み込み
os.chdir("C:\\PyTest")
# 作業用ディレクトリを変更
df= pd.read_csv("Data2.csv" , engine='python')
# データを読み込み
df['Index']=df.index
# 行番号の列を作る
fig = px.line(x = df['Index'], y = df['Y'])
# 折れ線グラフのデータを作る(X軸は行番号)
fig.show()
# 折れ線グラフを描く
Plotly --> 2次データの作成

まず、できるのが左のグラフで、細かい山がたくさんある様子がわかります。 拡大したのが右のグラフで、山と山の間に一定値の区間があることがわかります。 機械のデータだと、一定値の区間は、機械が止まっている場合になっていることが多いです。 また、ひとつの山の間に、機械が動いて加工をしています。

0と1のデータを追加する

実際のセンサーのデータだと、機械の状態を表すデータは、機械から出力されていることもあるのですが、 ここではないので、作ります。 機械が止まっている時は、Yは0になっているようなので、それを使ってデータを作ります。

df['X01']=df.Y.apply(lambda x:0 if x<=0 else 1)# 0より大きければ1、それ以外は0にした変数を作る

1.5次データの作成と分析

周期が変わるごとに0からスタートして、周期内では1ずつ増えていく列(X02,X04)を作ります。

また、次の周期になるごとに1ずつ増える列(X03,X05)を作ります。

X02とX03は、0が1に変わったタイミングをスタートにしています。 1.5次データの分析には便利です。

X04とX05は、1が0に変わったタイミングをスタートにしています。 停止時(0の時)の影響が稼働時(1の時)に起きているのかを分析したい時は使います。

df['X01_diff']=df.X01.diff() # フラグ(X01)の差分のデータをる
df['X02'] = (df['X01_diff'] == 1).cumsum()
# 差分のデータが「1」の時に累積する
df['X03']=df.groupby('X02').cumcount()+1
# グループ変数を作る
df['X04'] = (df['X01_diff'] == -1).cumsum()
# 差分のデータが「-1」の時に累積する
df['X05']=df.groupby('X04').cumcount()+1
# グループ変数を作る
2次データの作成
2次データの作成

ここまでで 1.5次データ になります。
下記のコードで、周期ごとで色分けしたグラフを作れます。
sns.lineplot(data=df, x='X03', y='Y',hue='X02') # 層別の折れ線グラフを描く
2次データの作成

2次データの作成と分析

2次データ を作って分析していくことになります。 ここでは比較的汎用的で、一度は確認しておいた方が良いような特徴量の作り方になります。 メタ知識 を駆使した特徴量を作る時にも、応用できます。

df20=pd.DataFrame(df[df.X01 == 0].groupby(['X04']).X01.count()) # X01が0のデータの個数
df20 = df20.rename(columns={'X01': 'n_0'})
# 変数名を変更
df21=pd.DataFrame(df[df.X01 == 1].groupby(['X04']).X01.count())
# X01が1のデータの個数
df21 = df21.rename(columns={'X01': 'n_1'})
# 変数名を変更
df31=pd.DataFrame(df[df.X01 == 1].groupby(['X04']).Y.max())
# グループ毎に、X01が1の時のYの最大値を計算
df31 = df31.rename(columns={'Y': 'Max_Y_1'})
# 変数名を変更
df32=pd.DataFrame(df[df.X01 == 1].groupby(['X04']).Y.min())
# グループ毎に、X01が1の時のYの最小値を計算
df32 = df32.rename(columns={'Y': 'Min_Y_1'})
# 変数名を変更
df2 = pd.concat([df20, df21,df31,df32], axis=1)
# グループ毎の計算値をひとつの表にまとめる。
2次データの作成

変数名は下記になります。
n_0 : X01が0のデータの個数。このデータの場合は、1秒毎のデータなので、X01が0の時間(秒)の意味になる。
n_1 : X01が1のデータの個数。このデータの場合は、1秒毎のデータなので、X01が1の時間(秒)の意味になる。
Max_Y_1 : X01が1の時のYの最大値
Min_Y_1 : X01が1の時のYの最小値

n_0とMax_Y_1で散布図を描くと、きれいに一直線に並んでいます。 つまり、X01が0の時間が長いと、Yの最大値が高いことがわかります。
1次データや1.5次データを眺めているだけでは、こうした分析結果を出すのは難しいのですが、2次データにすると、簡単に出せます。
sns.scatterplot(data=df2, x='n_0', y='Max_Y_1') # 散布図を描く
2次データの作成

工場のデータ分析のノウハウ

上の分析例の意味は、「機械が動いている時の最大値は、その直前に機械が止まっている時間に比例している」というものです。

機械の加工に異常があった時は、まず機械が動いてる時のデータに目が行きます。 例えば、加工に異常があった時は、Yのデータが高い時であることは、この見方で気づけます。

しかし、「なぜ、高い時があるのか?」は、機械が動いている時のデータをいくら見てもわかりません。

こんな時に、機械が止まっている時間の状況も調べると、原因究明のヒントになることがあります。 上記の例だと、機械が止まっている時間と、Yのデータの最大値には関係があることがヒントになる可能性があります。

このページのサンプルコードは、機械が止まっている時の情報も得られるように作っています。 このページの例では、機械が止まっている時は、Yは0で一定値なので、特に何もしていませんが、 機械が止まっている時のYの最大値や最小値を求めてみると良いこともあります。

3次データの作成と分析

工場のデータ分析では、2次データを作るところでは終わらず、品質や機械の状態のデータと紐付けて 3次データ を作らないと、やりたいことにつながらないです。

センサーデータの中に、紐付けに使えるIDのようなものがあれば楽なのですが、ない場合、 時刻のデータを見比べて、紐付けるしかありません。

プログラミングでスマートにできることは稀で、時には1個ずつ手で紐付ける作業が必要になることもあります。



Tweet データサイエンス教室